package com.zzyl.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.zzyl.base.PageBean;
import com.zzyl.dto.*;
import com.zzyl.entity.*;
import com.zzyl.enums.BalanceStatusEnum;
import com.zzyl.enums.CheckInStatusEnum;
import com.zzyl.mapper.*;
import com.zzyl.service.CheckInService;
import com.zzyl.service.ElderService;
import com.zzyl.vo.*;
import com.zzyl.vo.retreat.ElderVo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

@Service
@RequiredArgsConstructor
@Slf4j
public class CheckInServiceImpl implements CheckInService {

    final ElderService elderService;

    final CheckInMapper checkInMapper;

    final CheckInConfigMapper checkInConfigMapper;

    final ContractMapper contractMapper;

    final BedMapper bedMapper;

    final ElderMapper elderMapper;

    final MemberMapper memberMapper;

    final MemberElderMapper memberElderMapper;

    final BalanceMapper balanceMapper;


    /**
     * 分页查询
     *
     * @param elderName 老人姓名，模糊查询
     * @param idCardNo  身份证号，精确查询
     * @param pageNum   页码
     * @param pageSize  页面大小
     * @return 分页结果
     */
    @Override
    public PageBean<CheckInPageQueryVo> pageQuery(String elderName, String idCardNo, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);

        //老人姓名，模糊查询，这里进行预处理
        elderName = CharSequenceUtil.isBlank(elderName) ? null : "%" + elderName + "%";

        //这里只查询入住状态的
        Page<CheckInPageQueryVo> pageResult = checkInMapper.selectByPage(elderName, idCardNo, CheckInStatusEnum.PROGRESSING.getOrdinal());
        return PageBean.of(pageResult, CheckInPageQueryVo.class);
    }

    /**
     * 入住详情
     *
     * @param id 入住id
     * @return 入住详情
     */
    @Override
    public CheckInDetailVo detail(Long id) {
        //入住信息
        CheckIn checkIn = checkInMapper.selectById(id);

        //老人信息
        ElderVo elderVo = elderService.selectByPrimaryKey(checkIn.getElderId());
        CheckInElderVo checkInElderVo = BeanUtil.toBean(elderVo, CheckInElderVo.class);
        checkInElderVo.setOneInchPhoto(elderVo.getImage());

        //入住配置信息
        CheckInConfig checkInConfig = checkInConfigMapper.findCurrentConfigByElderId(checkIn.getElderId());

        //合同信息
        Contract contract = contractMapper.selectByContractNo(checkIn.getRemark());

        //封装响应信息
        CheckInDetailVo checkInDetailVo = new CheckInDetailVo();
        checkInDetailVo.setCheckInElderVo(checkInElderVo);
        checkInDetailVo.setElderFamilyVoList(JSONUtil.toList(checkIn.getOtherApplyInfo(), ElderFamilyVo.class));
        checkInDetailVo.setCheckInConfigVo(BeanUtil.toBean(checkInConfig, CheckInConfigVo.class));
        checkInDetailVo.setCheckInContractVo(BeanUtil.toBean(contract, CheckInContractVo.class));
        return checkInDetailVo;
    }

    /**
     * 申请入住
     *
     * @param checkInApplyDto 申请入住Dto
     * @author YiSheep
     */
    @Override
    public void apply(CheckInApplyDto checkInApplyDto) {
        //1.更新床位状态
        //获取入住配置信息
        CheckInConfigDto checkInConfigDto = checkInApplyDto.getCheckInConfigDto();
        Bed bed = Bed.builder().id(checkInConfigDto.getBedId())
                .bedStatus(1).build();
        bedMapper.update(bed);
        bed = bedMapper.getById(checkInConfigDto.getBedId());
        //2.新增老人（或更新，老人可能以前入住过。如果数据库存在老人信息就是更新，不存在就是新增）
        //获取老人信息
        CheckInElderDto checkInElderDto = checkInApplyDto.getCheckInElderDto();
        Elder elder = BeanUtil.toBean(checkInElderDto, Elder.class);
        Elder oldElder = elderMapper.selectByIdCardAndName(elder.getIdCardNo(), elder.getName());
        log.error("oldElder:" + oldElder);

        if (ObjectUtil.isEmpty(oldElder)) {
            elder.setImage(checkInElderDto.getOneInchPhoto());
            elder.setStatus(0); //0入住中 1已退住 ElderStatusEnum
            elder.setBedId(bed.id);
            elder.setBedNumber(bed.getBedNumber());
            elderMapper.insert(elder);
        } else {
            elder.setId(oldElder.getId());
            elder.setImage(checkInElderDto.getOneInchPhoto());
            elder.setStatus(0); //0入住中 1已退住 ElderStatusEnum
            elder.setBedId(bed.id);
            elder.setBedNumber(bed.getBedNumber());
            elderMapper.updateByPrimaryKeySelective(elder);
        }
        //3.新增老人家属信息(会员)
        //获取家属信息
        List<ElderFamilyDto> elderFamilyDtoList = checkInApplyDto.getElderFamilyDtoList();
        elderFamilyDtoList.forEach(elderFamilyDto -> {
            Member member = Member.builder().name(elderFamilyDto.getName()).phone(elderFamilyDto.getPhone()).build();
            member.setOpenId(RandomUtil.randomString(28));
            memberMapper.save(member);
            MemberElder memberElder = MemberElder.builder().memberId(member.getId()).elderId(elder.getId()).remark(elderFamilyDto.getKinship()).build();
            memberElderMapper.add(memberElder);
        });
        //4.新增入住信息
        // 定义日期时间格式器
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

        // 将当前时间格式化为字符串
        String formattedDateTime = LocalDateTime.now().format(formatter);

        String checkInCode = "RZ" + formattedDateTime + "1";//生成入住编码
        CheckIn checkIn = CheckIn.builder()
                .checkInCode(checkInCode)
                .title(elder.getName() + "的入住申请")
                .elderId(elder.getId())
                .checkInTime(LocalDateTime.now())
                .applicat("管理员")//获取当前登录人的信息
                .deptNo("100001001000000")
                .applicatId(1671403256519078138L)
                .status(0)//0入住中   1已退住
                .otherApplyInfo(JSONUtil.toJsonStr(checkInApplyDto.getElderFamilyDtoList())).build();


        // 拼接字符串
        String dateTimeString = "HT" + formattedDateTime + "1";
        checkIn.setRemark(dateTimeString);
        checkInMapper.insert(checkIn);
        //5.新增入住配置
        CheckInConfig checkInConfig = BeanUtil.toBean(checkInApplyDto.getCheckInConfigDto(), CheckInConfig.class);
        checkInConfig.setElderId(elder.getId());
        checkInConfig.setBedNumber(bed.getBedNumber());
        checkInConfig.setCheckInCode(checkIn.getCheckInCode());
        String remark = checkInApplyDto.getCheckInConfigDto().getFloorId()
                + ":" + checkInApplyDto.getCheckInConfigDto().getRoomId()
                + ":" + checkInApplyDto.getCheckInConfigDto().getBedId()
                + ":" + checkInApplyDto.getCheckInConfigDto().getFloorName()
                + ":" + checkInApplyDto.getCheckInConfigDto().getCode();
        checkInConfig.setRemark(remark);
        checkInConfigMapper.insert(checkInConfig);
        //6.新增合同，如果入住开始时间小于当前时间，则合同状态设为生效中，否则为待生效
        //获取合同信息
        CheckInContractDto checkInContractDto = checkInApplyDto.getCheckInContractDto();
        Contract contract = BeanUtil.toBean(checkInContractDto, Contract.class);
        contract.setContractNo(dateTimeString);
        contract.setCheckInNo(checkInCode);
        contract.setElderId(elder.getId());
        contract.setElderName(elder.getName());
        contract.setStatus(1);//合同状态
        contract.setStartTime(checkInConfigDto.getCheckInStartTime());
        contract.setEndTime(checkInConfigDto.getCheckInEndTime());
        contractMapper.insert(contract);
        //7.新增或更新余额信息
        Balance balance = new Balance();
        balance.setElderId(elder.getId());
        balance.setElderName(elder.getName());
        balance.setBedNo(elder.getBedNumber());
        balance.setDepositAmount(checkInConfig.getDepositAmount());
        balance.setPrepaidBalance(new BigDecimal(0));
        balance.setArrearsAmount(new BigDecimal(0));
        balance.setStatus(BalanceStatusEnum.NORMAL.getOrdinal());

        Balance dbBalance = balanceMapper.selectByElderId(elder.getId());
        if (ObjectUtil.isNotEmpty(dbBalance)) {
            balance.setId(dbBalance.getId());
            balanceMapper.updateByPrimaryKeySelective(balance);
        } else {
            balanceMapper.insert(balance);
        }
        //TODO 8.新增首月账单，生成首月账单
        //TODO 9.生成护理任务
    }
}
